<html>
   <body style="overflow: hidden;">
   <button onclick="soundPlay()">Play</button><br/>
   <button onclick="createCharacter()">Character</button><input id="debugInput" /><br/>
   <button onclick="createCharacter2()">Character2</button><br/>
   <script src="./core/resource.js"></script>
   <script src="./core/sound.js"></script>
   <script src="./core/character.js"></script>
   <script>
      // the test.html uses wz from v062
      var env = { action: 'stand1', bitmap: { stand: 1, left: 0, right: 0, prone: 0, jump: 0 } };
      var test = new MapleSound('/Sound.wz/Bgm02.img/MissingYou');
      function soundPlay () {
         test.Play();
      }

      function createCharacter() {
         var char = new MapleCharacterSimple({
            head: '/Character.wz/00012004.img/front/head',
            body: '/Character.wz/00002004.img/stand1/0/body',
            arm: '/Character.wz/00002004.img/stand1/0/arm',
            _: {
               head: {x: 0, y: 0, z:1},
               body: {x: 5, y: 34, z:0},
               arm: {x: 21, y: 35, z:10}
            }
         });
         char.Assemble().then(function () {
            var img = document.createElement('img');
            // img.id = 'debugImg';
            img.style.position = 'absolute';
            img.src = char.ImageURLBlob();
            document.body.appendChild(img);
         });
      }

      function createCharacter2() {
         var char = new MapleCharacter('2004');
         char.Assemble().then(function () {
            env.char = char;
            var canvas = document.createElement('canvas');
            var pen = canvas.getContext('2d');
            var img = char.Image();
            var index = 0;
            var lastAction, val;
            env.canvas = canvas;
            env.pen = pen;
            document.body.appendChild(canvas);
            env.lastAction = 'stand1';
            env.char.Animate('stand1', animate);
         });
      }

      function animate(char) {
         if (!env.canvas || !env.pen) return;
         env.canvas.style.position = 'absolute';
         env.canvas.width = char.w;
         env.canvas.height = char.h;
         env.canvas.style.width = char.w + 'px';
         env.canvas.style.height = char.h + 'px';
         env.pen.clearRect(0, 0, char.w, char.h);
         env.pen.putImageData(char.Image(), 0, 0);
      }

      function changeAnimate(type) {
         if (!env.char || !env.move) return;
         env.lastOrigin = env.char.GetOrigin();
         env.lastAction = type;
         env.char.Animate(type, animate);
         var align = env.char.AlignOrigin(env.lastOrigin.x, env.lastOrigin.y);
         env.move.style.left = (env.move.offsetLeft + align.x) + 'px';
         env.move.style.top = (env.move.offsetTop + align.y) + 'px';
      }

      document.body.addEventListener('click', function (evt) {
         if (evt.which !== 1) return;
         if (env.move) {
            env.move = null;
            return;
         }
         if (['img', 'canvas'].indexOf(evt.target.tagName.toLowerCase()) < 0) return;
         env.move = evt.target;
      });
      document.body.addEventListener('mousemove', function (evt) {
         if (!env.move) return;
         env.move.style.top = (evt.clientY - env.move.offsetHeight / 2) + 'px';
         env.move.style.left = (evt.clientX - env.move.offsetWidth / 2) + 'px';
      });
      document.body.addEventListener('keyup', function (evt) {
         if (!env.move) return;
         switch(env.move.tagName.toLowerCase()) {
            case 'canvas': canvas_move(); break;
         }
         function canvas_move() {
            if (env.jump) return;
            switch(evt.code) {
            case 'ArrowLeft':
               if (!env.bitmap.left) return;
               if (!env.move) return;
               env.bitmap.left = 0;
               if (env.bitmap.jump) return;
               env.bitmap.stand = 1;
               changeAnimate('stand1');
               return;
            case 'ArrowRight':
               if (!env.bitmap.right) return;
               if (!env.move) return;
               env.bitmap.right = 0;
               if (env.bitmap.jump) return;
               env.bitmap.stand = 1;
               changeAnimate('stand1');
               return;
            case 'ArrowDown':
               if (!env.bitmap.prone) return;
               if (!env.move) return;
               env.bitmap.prone = 0;
               env.bitmap.stand = 1;
               changeAnimate('stand1');
               return;
            }
         }
      });
      document.body.addEventListener('keydown', function (evt) {
         if (!env.move) return;
         switch(env.move.tagName.toLowerCase()) {
            case 'img': img_move(); break;
            case 'canvas': canvas_move(); break;
         }
         function img_move() {
            switch(evt.code) {
            case 'ArrowLeft':
               if (env.move.offsetLeft <= 0) return;
               env.move.style.left = (env.move.offsetLeft - 10) + 'px';
               return;
            case 'ArrowRight':
               if (env.move.offsetLeft + env.move.offsetWidth >= window.innerWidth) return;
               env.move.style.left = (env.move.offsetLeft + 10) + 'px';
               return;
            case 'ArrowUp':
               if (env.move.offsetTop <= 0) return;
               env.move.style.top = (env.move.offsetTop - 10) + 'px';
               return;
            case 'ArrowDown':
               if (env.move.offsetTop + env.move.offsetHeight >= window.innerHeight) return;
               env.move.style.top = (env.move.offsetTop + 10) + 'px';
               return;
            }
         }
         function canvas_move() {
            switch(evt.code) {
            case 'ArrowLeft':
               if (env.bitmap.prone) return;
               env.bitmap.left = 1;
               if (env.bitmap.jump) return;
               if (env.move.offsetLeft <= 0) return;
               env.move.style.left = (env.move.offsetLeft - 10) + 'px';
               env.char.mirrorX = false;
               if (env.lastAction === 'walk1') return;
               env.bitmap.stand = 0;
               changeAnimate('walk1');
               return;
            case 'ArrowRight':
               if (env.bitmap.prone) return;
               env.bitmap.right = 1;
               if (env.bitmap.jump) return;
               if (env.move.offsetLeft + env.move.offsetWidth >= window.innerWidth) return;
               env.move.style.left = (env.move.offsetLeft + 10) + 'px';
               env.char.mirrorX = true;
               if (env.lastAction === 'walk1') return;
               env.bitmap.stand = 0;
               changeAnimate('walk1');
               return;
            case 'ArrowUp':
               if (env.bitmap.prone) return;
               if (env.lastAction === 'jump') return;
               env.bitmap.stand = 0;
               env.bitmap.jump = 1;
               changeAnimate('jump');
               jump({ index: 0, base: env.move.offsetTop, ceil: 50 });

               function jump(jump_env) {
                  var frame_count = 8, half_fc = frame_count / 2;
                  var x = jump_env.index;
                  if (jump_env.index > frame_count) {
                     env.bitmap.jump = 0;
                     env.bitmap.left = 0;
                     env.bitmap.right = 0;
                     env.bitmap.stand = 1;
                     env.move.style.top = jump_env.base + 'px';
                     changeAnimate('stand1');
                     return;
                  }
                  var top = jump_env.base - (1 - (x - half_fc) * (x - half_fc) / half_fc / half_fc) * jump_env.ceil;
                  env.move.style.top = top + 'px';
                  if (env.bitmap.left) {
                     env.char.mirrorX = false;
                     if (env.move.offsetLeft <= 0) return;
                     env.move.style.left = (env.move.offsetLeft - 10) + 'px';
                  } else if (env.bitmap.right) {
                     env.char.mirrorX = true;
                     if (env.move.offsetLeft + env.move.offsetWidth >= window.innerWidth) return;
                     env.move.style.left = (env.move.offsetLeft + 10) + 'px';
                  }
                  jump_env.index ++;
                  setTimeout(jump, 100, jump_env);
               }
               return;
            case 'ArrowDown':
               if (env.bitmap.jump) return;
               if (env.lastAction === 'prone') return;
               env.bitmap.stand = 0;
               env.bitmap.prone = 1;
               changeAnimate('prone');
               return;
            }
         }
      });
      document.querySelector('#debugInput').addEventListener('keypress', charOpen);
      function charOpen(evt) {
         if (evt.code !== 'Enter') return;
         var input = document.querySelector('#debugInput');
         MapleResourceManager.Get(input.value, 'image').then(function (obj) {
            console.log(obj);
            if (obj.type !== 'image') return;
            // var img = document.querySelector('#debugImg');
            var img;
            if (!img) img = document.createElement('img');
            // img.id = 'debugImg';
            img.style.position = 'absolute';
            env.u8 = obj.u8;
            env.char = new MapleSprite(obj.u8, obj.data.width, obj.data.height);
            img.src = env.char.ImageURLBlob();
            document.body.appendChild(img);
         });
      }
   </script>
   </body>
</html>